在前面的章節中,我們已經介紹了 Robot Framework 的檔案架構(*** Settings ***
, *** Test Cases ***
)。在有些分享程式碼執行過程的文章會說到,程式是由上至下一行行執行的,這個章節便是要探索 Robot Framework 的執行過程,在一個 .robot
檔案中,階層為 Suite → Test → Keyword,如下圖所示。當測試觸發時,執行該 .robot 檔案時,會按照這個流程依次執行。執行完成後,系統會決定是繼續執行下一個 .robot
測試,還是進入報告生成的流程。
接著我們針對 Suite、Test、Keyword 來做更多的介紹:
Suite 顧名思義是測試的集合,我們可以先將一個 .robot
的檔案視為一個 Test Suite 的概念,因此在一個檔案中可以有許多的 Test Case,透過 Test Suite 我們可以很好的管理測試之間的差異,同時,在 Robot Framework 中還有提供 Setup、Teardown 的功能,讓我們可以在測試一開始時就先完成特定的前置步驟,通常有關 Suite 的設定,我們會將它放在 *** Settings ***
的區塊中,以下是 Suite 可以客製化的參數:
這邊的 Name 是用來設定 test suite 的名稱的,在預設的情況下,在報告中我們會看到的 name 都是透過 路徑 + 檔案名稱所組成的,因此如果檔案名稱取名的比較難以理解是,會造成我們在閱讀報告的困難。
適用在當今天 Name 不夠寫,需要有更長的說明時,可以透過 Documentation 來撰寫,關於撰寫的一些規範可以參考官方的: Documentation formatting。
當我們設定 Metadata 後,可以在測試的報告中看見設定的值
Suite Setup 發生的時機點會是在執行 Test Case 前,每個 .robot
的檔案在開始執行時都會最先執行 Suite Setup,接著在執行底下的多個 case,不過當然如果我們沒有指定說需要的話也就不會執行這個部分,通常我們會在 Suite Setup 做前置條件的行為像是在 Web 自動化測試中,我們可以需要先進行登入,而不是每個 test case 執行時都登入,這樣一來便可以節省下每次測試案例開始都需要先登入的執行時間,讓測試更聚焦在測試案例本身,並且當 Suite Setup 執行失敗時,其底下的 test case 都會直接 fail,並不會執行,如此一來可以避免沒有執行前置步驟卻還執行測試案例導致測試案例花時間執行還全部錯誤的窘境發生。
Suite Teardown 與 Suite Setup 是相同的道理,只是是在 Suite 執行結束前執行,因此可以作為測試數據的清理,像是測試結束後將測試過程中新增的資料做刪除。
下面我們透過這一小段 Demo Code 來看看實際效果吧!
*** Settings ***
Documentation My First Robot Framework
Name 測試 Settings Name
Metadata 測試 Metadata Metadata 測試
Suite Setup Log To Console message=Print Suite Setup
Suite Teardown Log To Console message=Print Suite Teardown
*** Test Cases ***
Test Case 001
Log To Console message=Print Test Case 001
Test Case 002
Log To Console message=Print Test Case 002
執行過後我們可以在終端機看到,我們的 Name 指定成"測試 Settings Name"在終端機上也有如實呈現,以及我們有兩個 Test Case,並且在 Suite Setup
、 Suite Teardown
加上 Log To Console
,可以觀察到執行的順序為 Print Suite Setup → Print Test Case 001 → Print Test Case 002 → Print Suite Teardown。
==============================================================================
測試 Settings Name :: My First Robot Framework
==============================================================================
Print Suite Setup
Test Case 001 Print Test Case 001
Test Case 001 | PASS |
------------------------------------------------------------------------------
Test Case 002 Print Test Case 002
Test Case 002 | PASS |
------------------------------------------------------------------------------
Print Suite Teardown
測試 Settings Name :: My First Robot Framework | PASS |
2 tests, 2 passed, 0 failed
==============================================================================
Output: ithome/output.xml
Log: ithome/log.html
Report: ithome/report.htm
我們會將要執行的 test case 放在 *** Test Cases ***
區塊中,然而每個 Test Case 也可以有自己的設定,設置的位置是在 test case 名稱的下一行,並且需要縮排,下面我們一起來看看有哪些值可以設定,以及範例吧!
在這邊我們可以針對該 test case 轉寫些註釋。
Test Case 001
[Documentation] test case 001 doc
${sum} = Sum Two Number num1=1 num2=2
Should Be Equal As Integers first=${sum} second=${3}
Tags 在 Robot Framework 是一個相當強大的機制,它讓我們可以輕鬆的對 test case 進行分類,像是我們可以在 tags 裡寫 smoke 或是 release,這樣當我們在下 Robot Framework 執行的指令時,便可以透過這個 tag 來做 filter,下面舉個例,目前我有兩個 test case,其中一個 tag 是 smoke,另一個是 release:
*** Settings ***
Documentation Test Tags
*** Test Cases ***
Test Case 001
[Tags] smoke release
Log message=Print Test Case 001
Test Case 002
[Tags] release
Log message=Print Test Case 002
當今天我們透過 robot test.robot 觸發測試時,兩隻 case 都會被執行到
➜ robot test.robot
==============================================================================
Test :: Test Tags
==============================================================================
Test Case 001 | PASS |
------------------------------------------------------------------------------
Test Case 002 | PASS |
------------------------------------------------------------------------------
Test :: Test Tags | PASS |
2 tests, 2 passed, 0 failed
==============================================================================
但是當我今天的指令透過 -i
時,便會 filter 出 tags 中包含 smoke 的 test case:
➜ robot -i smoke test.robot
==============================================================================
Test :: Test Tags
==============================================================================
Test Case 001 | PASS |
------------------------------------------------------------------------------
Test :: Test Tags | PASS |
1 test, 1 passed, 0 failed
=============================================================================
並且 [Tags] 是接受多個 tag 的,像是 Test Case 001 可以同時是 smoke 又是 release,這樣當我們在執行測試時,只要有一個值包含,便會被 filter 出來執行測試了。
測試案例的超時(Timeout)可以在 Setting 區域使用 Test Timeout
設定,也可以在個別測試案例中使用 [Timeout] 設定。Test Timeout
在 *** Settings ***
區塊時會為整個測試套件中的測試案例設置預設超時,而 [Timeout]
則針對單個測試案例設定並會覆蓋預設值。超時的參數可用 Robot Framework 的時間格式指定,如果超時發生,當前執行的關鍵字將停止並標記測試失敗,但 Test Teardown 中的關鍵字不會被中斷,這點相當相當重要,過去作者曾經犯了個失誤,是在 Test Teardown 做了相對複雜的 UI 操作,但是由於 Test Teardown 不受 Timeout 的制約,因此測試足足卡了好幾個小時直到發現才手動取消。
*** Settings ***
Documentation Test Timeout
*** Test Cases ***
Test Case 001
[Timeout] 10s
Log message=Print Test Case 001
Template 測試模板,這在 Robot Framework 是個非常有趣的用法,他可以將普通的 keyword 變成數據驅動的測試,顧名思義就是,有個測試模板,我們只需要帶參數給他,他會幫我們逐行執行到所有的數據,且即使某行失敗,其餘部分仍會繼續執行。這種方式使得管理大量相似測試更加高效,能有效的減少重複程式碼,使測試更具可讀性和可維護,可以看到下方的案例,我們創建一個 Log Template 的 keyword,它可以接收兩個參數,並且將參數打印出來,而在 test case 中帶入了三行的參數,預期要透過 Template 迭代三次:
*** Settings ***
Documentation Test Template
*** Test Cases ***
Test Case 001
[Template] Log Template
msg1_1 msg2_1
msg1_2 msg2_2
msg1_3 msg2_3
*** Keywords ***
Log Template
[Arguments] ${msg1} ${msg2}
Log To Console msg1=${msg1} & msg2=${msg2}
最後的結果也與我們與其的相同,打印出 msg1=msg1_1 & msg2=msg2_1、msg1=msg1_2 & msg2=msg2_2、msg1=msg1_3 & msg2=msg2_3 這三種。
==============================================================================
Test :: Test Timeout
==============================================================================
Test Case 001 msg1=msg1_1 & msg2=msg2_1
.msg1=msg1_2 & msg2=msg2_2
.msg1=msg1_3 & msg2=msg2_3
Test Case 001 | PASS |
------------------------------------------------------------------------------
Test :: Test Timeout | PASS |
1 test, 1 passed, 0 failed
==============================================================================
在 test case 中我們可以設定單獨 test case 的 setup,然而在 *** Settings ***
我們也可以使用 Test Setup
,在 *** Settings ***
使用的話,會是所有的 test case 都使用相同的 Test Setup,如果放在 case 裡面的話,則會覆蓋掉 *** Settings ***
裡面的,執行屬於他自己的。
我們可以直接看範例,在下方我們有一個在 *** Settings ***
區塊中的 Test Setup
,以及在 Test Case 001
中有 [Setup]
,因此我們預期 Test Case 001
的 [Setup]
會覆蓋掉 Settings 中的,所以 Test Case 001 會印出 Case 的 Test Setup,而 Test Case 002 因為沒有 [Setup] 所以則是印出 Settings 的 Test Setup。
*** Settings ***
Documentation Test Setup
Test Setup Log To Console Settings 的 Test Setup
*** Test Cases ***
Test Case 001
[Setup] Log To Console Case 的 Test Setup
Log Test Case 001
Test Case 002
Log Test Case 002
執行後發現,跟我們預期的相同!
==============================================================================
Test :: Test Setup
==============================================================================
Test Case 001 Case 的 Test Setup
Test Case 001 | PASS |
------------------------------------------------------------------------------
Test Case 002 Settings 的 Test Setup
Test Case 002 | PASS |
------------------------------------------------------------------------------
Test :: Test Setup | PASS |
2 tests, 2 passed, 0 failed
==============================================================================
Test Teardown 與 Test Setup 是相同的道理,因此就不在多做贅述。
我們可以將 Keyword 想要成是測試步驟,在一個 test case 中可以同時擁有許多的 Keyword,使用 Keyword 時與使用 Test 相當相似,下面我們一起來看看有哪些值可以設定吧!
在這邊我們可以針對該 Keyword 轉寫些註釋。
在 Keyword 中我們是可以設定 tag 的,但是由於這種情境較少使用到,因此如果需要了解更多可以查看官方文件。
Arguments 的功能就很像是我們在寫 python 的 func 時指定該 func 可以帶入的參數,與 python 一樣,它也支援吃預設值的模式,雖然參數名稱對框架來說並不重要,但對於使用者而言,名稱應該儘量具有描述性,並且建議使用小寫字母來命名,例如 ${my_arg}、${my arg} 或 ${myArg},讓我們一起來看看範例:
*** Settings ***
Documentation Test Arguments
*** Test Cases ***
Test Case 001
[Tags] smoke
${sum} = Sum Two Number 1 1
Log To Console ${sum}
Test Case 002
[Tags] release
${sum} = Sum Two Number num1=2
Log To Console ${sum}
*** Keywords ***
Sum Two Number
[Arguments] ${num1} ${num2}=1
${sum} = Evaluate ${num1}+${num2}
RETURN ${sum}
回傳的結果也有符合我們的預期:
==============================================================================
Test :: Test Tags
==============================================================================
Test Case 001 .2
Test Case 001 | PASS |
------------------------------------------------------------------------------
Test Case 002 .3
Test Case 002 | PASS |
------------------------------------------------------------------------------
Test :: Test Tags | PASS |
2 tests, 2 passed, 0 failed
==============================================================================
與前面的概念相同,因此這邊就不多做說明了。
就像是 python func 一樣,我們可以透過 RETURN 來回傳 keyword 產生的值,如果看網路上其他較早期的文章可能會看到 [RETURN] 這樣的用法,這是早期的 return 方式,在 Robot Framework 7.0 中已棄用,並且內建關鍵字內的 Return From Keyword
和 Return From Keyword If
也被視為已棄
*** Keywords ***
Sum Two Number
[Arguments] ${num1} ${num2}=1
${sum} = Evaluate ${num1}+${num2}
RETURN ${sum}
這個章節的篇幅稍微長了一點,不過能夠理解 Robot Framework 執行的流程對於我們在設計測試上有很大的幫助,透過合理的 Suite Setup 和 Teardown 設定,我們可以更有效且彈性的減少重複性的操作、提高測試效率,Tags、Timeout 和 Template 的使用,則進一步強化了測試的可管理性,再次感謝大家的觀看,下一章我們將要一起來看關於 Robot Framework 的 Control structures (控制結構)!